<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>学生管理</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
        }

        :root {
            --primary: #4F46E5;
            --primary-dark: #4338CA;
            --secondary: #10B981;
            --tertiary: #F59E0B;
            --light: #F9FAFB;
            --dark: #1F2937;
            --gray: #6B7280;
            --light-gray: #E5E7EB;
            --border: #D1D5DB;
            --card-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
            --success: #10B981;
            --warning: #F59E0B;
        }

        body {
            background: linear-gradient(135deg, #f0f7ff 0%, #f8fafc 100%);
            color: var(--dark);
            min-height: 100vh;
            padding: 20px;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
        }

        header {
            background: white;
            border-radius: 16px;
            box-shadow: var(--card-shadow);
            padding: 20px 30px;
            margin-bottom: 30px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            flex-wrap: wrap;
            gap: 20px;
        }

        .logo {
            display: flex;
            align-items: center;
            gap: 12px;
            font-size: 1.5rem;
            font-weight: 700;
            color: var(--primary);
        }

        .logo i {
            font-size: 1.8rem;
        }

        .header-controls {
            display: flex;
            gap: 15px;
            flex-wrap: wrap;
            margin-top: 15px;
        }

        .class-filter {
            display: flex;
            align-items: center;
            gap: 10px;
        }

        select {
            padding: 10px 15px;
            border-radius: 8px;
            border: 1px solid var(--border);
            background: white;
            font-size: 1rem;
            min-width: 150px;
            cursor: pointer;
            transition: all 0.3s ease;
        }

        .action-btn {
            width: 36px;
            height: 36px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            background: var(--light);
            color: var(--gray);
            cursor: pointer;
            transition: all 0.3s ease;
        }

        .action-btn:hover {
            background: var(--primary);
            color: white;
            transform: scale(1.1);
        }

        select:focus {
            outline: none;
            border-color: var(--primary);
            box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.2);
        }

        .file-upload {
            position: relative;
            display: inline-block;
        }

        .file-upload-btn {
            display: inline-flex;
            align-items: center;
            gap: 8px;
            background: var(--primary);
            color: white;
            padding: 10px 20px;
            border-radius: 8px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
            border: none;
        }

        .file-upload-btn:hover {
            background: var(--primary-dark);
            transform: translateY(-2px);
        }

        .file-upload-btn.update {
            background: #60A5FA;
        }

        .file-upload-btn.reset {
            background: #DC2626;
        }

        .file-upload-btn.export {
            background: #16A34A;
        }

        #file-input {
            position: absolute;
            left: 0;
            top: 0;
            opacity: 0;
            width: 100%;
            height: 100%;
            cursor: pointer;
        }

        .stats {
            display: flex;
            gap: 15px;
            margin-top: 10px;
            flex-wrap: wrap;
        }

        .stat-card {
            background: var(--light);
            border-radius: 10px;
            padding: 12px 20px;
            display: flex;
            align-items: center;
            gap: 10px;
            min-width: 180px;
        }

        .stat-icon {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.2rem;
        }

        .stat-content {
            display: flex;
            flex-direction: column;
        }

        .stat-value {
            font-size: 1.4rem;
            font-weight: 700;
        }

        .stat-label {
            font-size: 0.9rem;
            color: var(--gray);
        }

        .table-container {
            background: white;
            border-radius: 16px;
            box-shadow: var(--card-shadow);
            padding: 25px;
            overflow-x: auto;
        }

        .table-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
            flex-wrap: wrap;
            gap: 15px;
        }

        .table-title {
            font-size: 1.5rem;
            font-weight: 600;
            color: var(--dark);
        }

        .search-box {
            display: flex;
            align-items: center;
            background: var(--light);
            border-radius: 8px;
            padding: 8px 15px;
            border: 1px solid var(--border);
        }

        .search-box input {
            border: none;
            background: transparent;
            padding: 5px 10px;
            font-size: 1rem;
            min-width: 215px;
        }

        .search-box input:focus {
            outline: none;
        }

        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
        }

        thead {
            background: var(--light);
        }

        th {
            padding: 15px;
            text-align: left;
            font-weight: 600;
            color: var(--dark);
            border-bottom: 2px solid var(--border);
            position: relative;
        }

        th:hover {
            background: #f3f4f6;
        }

        .sort-icon {
            position: absolute;
            right: 10px;
            color: var(--gray);
            font-size: 0.8rem;
        }

        td {
            padding: 15px;
            border-bottom: 1px solid var(--border);
        }

        tr:last-child td {
            border-bottom: none;
        }

        tr:hover {
            background: rgba(79, 70, 229, 0.05);
        }

        .student-id {
            font-weight: 600;
            color: var(--primary);
        }

        .class-badge {
            display: inline-block;
            padding: 4px 12px;
            border-radius: 20px;
            font-size: 0.85rem;
            font-weight: 500;
            background: #DBEAFE;
            color: #1D4ED8;
        }

        .empty-state {
            text-align: center;
            padding: 60px 20px;
            color: var(--gray);
        }

        .empty-state i {
            font-size: 4rem;
            color: var(--light-gray);
            margin-bottom: 20px;
        }

        .empty-state p {
            font-size: 1.2rem;
            max-width: 500px;
            margin: 0 auto;
        }

        .file-requirements {
            background: #F3F4F6;
            border-radius: 8px;
            padding: 15px;
            margin-top: 20px;
            font-size: 0.9rem;
        }

        .file-requirements h4 {
            margin-bottom: 10px;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        footer {
            text-align: center;
            padding: 30px 0;
            color: var(--gray);
            margin-top: 40px;
        }

        @media (max-width: 768px) {
            header {
                flex-direction: column;
                align-items: flex-start;
            }

            .header-controls {
                width: 100%;
            }

            .class-filter,
            .file-upload {
                width: 100%;
            }

            select {
                width: 100%;
            }

            .file-upload-btn {
                width: 100%;
                justify-content: center;
            }

            .stats {
                width: 100%;
            }

            .stat-card {
                flex: 1;
                min-width: 0;
            }

            th,
            td {
                padding: 10px;
                font-size: 0.9rem;
            }
        }

        @media (max-width: 480px) {
            .table-header {
                flex-direction: column;
                align-items: flex-start;
            }

            .search-box {
                width: 100%;
            }

            .search-box input {
                width: 100%;
            }

            .logo span {
                font-size: 1.2rem;
            }
        }
    </style>
</head>

<body>
    <div class="container">
        <header>
            <div class="logo">
                <i class="fas fa-user-graduate"></i>
                <span>学生信息管理系统</span>
            </div>

            <div class="header-controls">
                <div class="file-upload">
                    <button class="file-upload-btn">
                        <i class="fas fa-file-upload"></i>
                        上传Excel数据
                    </button>
                    <input type="file" id="file-input" accept=".xlsx, .xls">
                </div>
                <div class="file-upload">
                    <button class="file-upload-btn update">
                        <i class="fas fa-sync"></i> 更新数据
                    </button>

                    <button class="file-upload-btn reset">
                        <i class="fas fa-trash"></i> 重置数据
                    </button>

                    <button class="file-upload-btn export">
                        <i class="fas fa-download"></i> 导出数据
                    </button>
                </div>
                <div class="class-filter">
                    <label for="class-select"><i class="fas fa-filter"></i> 班级筛选：</label>
                    <select id="class-select">
                        <option value="all">全部班级</option>
                        <!-- 班级选项将动态生成 -->
                    </select>
                </div>
            </div>

            <div class="stats">
                <div class="stat-card">
                    <div class="stat-icon" style="background: #DBEAFE; color: #1D4ED8;">
                        <i class="fas fa-users"></i>
                    </div>
                    <div class="stat-content">
                        <div class="stat-value" id="total-students">0</div>
                        <div class="stat-label">学生总数</div>
                    </div>
                </div>

                <div class="stat-card">
                    <div class="stat-icon" style="background: #D1FAE5; color: #047857;">
                        <i class="fas fa-chalkboard-teacher"></i>
                    </div>
                    <div class="stat-content">
                        <div class="stat-value" id="class-count">0</div>
                        <div class="stat-label">班级数量</div>
                    </div>
                </div>
            </div>
        </header>

        <div class="table-container">
            <div class="table-header">
                <h2 class="table-title">学生信息列表</h2>
                <div class="search-box">
                    <i class="fas fa-search"></i>
                    <input type="text" id="search-input" placeholder="搜索学生姓名、考号或座号">
                </div>
            </div>

            <div id="table-content">
                <div class="empty-state">
                    <i class="fas fa-file-excel"></i>
                    <h3>暂无学生数据</h3>
                    <p>请上传Excel文件以加载学生数据</p>
                </div>
            </div>

            <div class="file-requirements">
                <h4><i class="fas fa-info-circle"></i> Excel文件要求：</h4>
                <p>表格必须包含以下列：<strong>班级</strong>、<strong>姓名</strong>、<strong>考号</strong>、<strong>座号</strong></p>
                <p>第一行应为表头，数据从第二行开始</p>
            </div>
        </div>

        <footer>
            <p>© 2025 学生信息管理系统 | 数据仅保存在浏览器内存中</p>
        </footer>
    </div>

    <script>
        // 中文表头到英文字段的映射
        const columnMapping = {
            '班级': 'class',
            '姓名': 'name',
            '考号': 'id',
            '座号': 'seat'
            // 移除了成绩映射
        };

        // DOM元素
        const fileInput = document.getElementById('file-input');
        const classSelect = document.getElementById('class-select');
        const searchInput = document.getElementById('search-input');
        const tableContent = document.getElementById('table-content');
        const totalStudents = document.getElementById('total-students');
        const classCount = document.getElementById('class-count');
        const updateBtn = document.querySelector('.update');
        const resetBtn = document.querySelector('.reset');
        const exportBtn = document.querySelector('.export');

        // 当前展示的数据
        let currentData = [];
        const STORAGE_KEY = 'student_data';

        // 从本地存储加载数据
        function loadLocalData() {
            const data = localStorage.getItem(STORAGE_KEY);
            return data ? JSON.parse(data) : null;
        }

        // 保存数据到本地存储
        function saveLocalData(data) {
            localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
        }

        // 从网络获取Excel数据
        async function fetchExcelData() {
            try {
                const response = await fetch('https://zc-oss2.oss-cn-hongkong.aliyuncs.com/lhsz/%E7%AC%AC%E4%B8%83%E5%91%A8.xlsx', {
                    mode: 'cors',
                    headers: {
                        'Origin': location.origin
                    }
                });

                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }

                const arrayBuffer = await response.arrayBuffer();
                const data = new Uint8Array(arrayBuffer);
                const workbook = XLSX.read(data, { type: 'array' });
                const worksheet = workbook.Sheets[workbook.SheetNames[0]];
                return XLSX.utils.sheet_to_json(worksheet);
            } catch (error) {
                console.error('网络请求详细错误:', error);
                alert(`网络请求失败: ${error.message}\n请检查网络连接或手动上传文件`);
                return null;
            }
        }

        // 处理Excel数据
        function processExcelData(data) {
            return data.map(row => {
                const newRow = {};
                for (const [chineseHeader, englishField] of Object.entries(columnMapping)) {
                    if (row[chineseHeader] !== undefined) {
                        newRow[englishField] = row[chineseHeader];
                    }
                }
                return newRow;
            });
        }

        // 处理数据并更新UI
        function processData(data) {
            currentData = data;
            saveLocalData(data);
            updateStats(data);
            updateClassSelect(data);
            renderTable(data);
        }

        // 显示初始空状态
        function showInitialEmptyState(errorMessage = '') {
            tableContent.innerHTML = `
                <div class="empty-state">
                    <i class="fas fa-exclamation-triangle"></i>
                    <h3>${errorMessage ? '数据加载失败' : '欢迎使用'}</h3>
                    <p>${errorMessage || '正在加载初始数据...'}</p>
                    ${errorMessage ? '<button onclick="fileInput.click()" class="retry-btn">点击重试</button>' : ''}
                </div>
            `;
        }

        // 更新统计信息
        function updateStats(data) {
            totalStudents.textContent = data.length;

            const classes = new Set(data.map(student => student.class));
            classCount.textContent = classes.size;
        }

        // 更新班级筛选下拉菜单
        function updateClassSelect(data) {
            while (classSelect.options.length > 1) {
                classSelect.remove(1);
            }

            const classes = [...new Set(data.map(student => student.class))];
            classes.sort((a, b) => {
                const numA = parseInt(a);
                const numB = parseInt(b);
                return !isNaN(numA) && !isNaN(numB) ? numA - numB : a.toString().localeCompare(b.toString());
            });

            classes.forEach(cls => {
                const option = document.createElement('option');
                option.value = cls;
                option.textContent = `班级 ${cls}`;
                classSelect.appendChild(option);
            });
        }

        // 渲染表格
        function renderTable(data) {
            if (data.length === 0) {
                tableContent.innerHTML = `
                    <div class="empty-state">
                        <i class="fas fa-user-slash"></i>
                        <h3>没有符合条件的学生</h3>
                        <p>请尝试更改筛选条件或搜索关键词</p>
                    </div>
                `;
                return;
            }

            let tableHTML = `
                <table>
                    <thead>
                        <tr>
                            <th>考号</th>
                            <th>姓名</th>
                            <th>班级</th>
                            <th>座号</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
            `;

            data.forEach(student => {
                tableHTML += `
                    <tr>
                        <td class="student-id">${student.id || '未提供'}</td>
                        <td>${student.name || '未提供'}</td>
                        <td><span class="class-badge">${student.class || '未提供'}</span></td>
                        <td>${student.seat || '未提供'}</td>
                        <td>
                            <div class="actions">
                                <div class="action-btn" title="查看详情" onclick="viewStudent('${student.id}')">
                                    <i class="fas fa-eye"></i>
                                </div>
                            </div>
                        </td>
                    </tr>
                `;
            });

            tableHTML += `
                    </tbody>
                </table>
            `;

            tableContent.innerHTML = tableHTML;
        }

        // 班级筛选
        classSelect.addEventListener('change', function () {
            filterData();
        });

        // 搜索功能
        searchInput.addEventListener('input', function () {
            filterData();
        });

        // 查看学生详情
        function viewStudent(studentId) {
            const student = currentData.find(s => s.id === studentId);
            if (student) {
                alert(`学生详情：\n姓名：${student.name}\n考号：${student.id}\n班级：${student.class}\n座号：${student.seat}`);
            }
        }
        // 筛选数据
        function filterData() {
            const selectedClass = classSelect.value;
            const searchTerm = searchInput.value.toLowerCase();

            let filteredData = [...currentData];

            if (selectedClass !== 'all') {
                filteredData = filteredData.filter(student =>
                    student.class && student.class.toString() === selectedClass.toString()
                );
            }

            if (searchTerm) {
                filteredData = filteredData.filter(student => {
                    const name = student.name ? student.name.toString().toLowerCase() : '';
                    const id = student.id ? student.id.toString().toLowerCase() : '';
                    const seat = student.seat ? student.seat.toString().toLowerCase() : '';
                    return name.includes(searchTerm) || id.includes(searchTerm) || seat.includes(searchTerm);
                });
            }

            updateStats(filteredData);
            renderTable(filteredData);
        }

        // 文件上传处理
        fileInput.addEventListener('change', function (e) {
            const file = e.target.files[0];
            if (!file) return;

            showInitialEmptyState('正在处理文件...');

            const reader = new FileReader();
            reader.onload = function (e) {
                try {
                    const data = new Uint8Array(e.target.result);
                    const workbook = XLSX.read(data, { type: 'array' });

                    if (workbook.SheetNames.length === 0) {
                        throw new Error('Excel文件不包含有效工作表');
                    }

                    const worksheet = workbook.Sheets[workbook.SheetNames[0]];
                    const jsonData = XLSX.utils.sheet_to_json(worksheet);

                    if (jsonData.length === 0) {
                        throw new Error('Excel文件不包含有效数据');
                    }

                    const processedData = processExcelData(jsonData);
                    processData(processedData);
                } catch (error) {
                    console.error('文件处理错误:', error);
                    alert(`文件处理失败: ${error.message}\n请确保文件格式正确`);
                    showInitialEmptyState();
                }
            };
            reader.onerror = function (e) {
                console.error('文件读取错误:', e);
                alert('文件读取失败，请重试');
                showInitialEmptyState();
            };
            reader.readAsArrayBuffer(file);
        });

        // 模拟文件上传功能
        document.querySelector('.file-upload-btn').addEventListener('click', function () {
            if (!fileInput.files.length) {
                fileInput.click();
            }
        });

        // 新增功能：更新数据
        updateBtn.addEventListener('click', function () {
            showInitialEmptyState('正在更新数据...');
            fetchExcelData().then(networkData => {
                if (networkData) {
                    const processedData = processExcelData(networkData);
                    processData(processedData);
                } else {
                    showInitialEmptyState('网络请求失败，请手动上传文件');
                }
            });
        });

        // 新增功能：重置数据
        resetBtn.addEventListener('click', function () {
            if (confirm('确定要重置所有数据吗？')) {
                currentData = [];
                localStorage.removeItem(STORAGE_KEY);
                updateStats([]);
                updateClassSelect([]);
                renderTable([]);
                showInitialEmptyState('数据已重置');
            }
        });

        // 新增功能：导出数据
        exportBtn.addEventListener('click', function () {
            if (currentData.length === 0) {
                alert('没有可导出的数据');
                return;
            }

            const workbook = XLSX.utils.book_new();
            // 直接使用中文表头对应的字段生成数据，不再额外添加英文表头行
            const exportData = currentData.map(student => ({
                班级: student.class,
                姓名: student.name,
                考号: student.id,
                座号: student.seat
            }));
            const worksheet = XLSX.utils.json_to_sheet(exportData);
            XLSX.utils.book_append_sheet(workbook, worksheet, '学生数据');

            const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
            const blob = new Blob([excelBuffer], { type: 'application/octet-stream' });
            const url = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = '学生数据.xlsx';
            a.click();
            window.URL.revokeObjectURL(url);
        });

        // 初始化页面
        document.addEventListener('DOMContentLoaded', function () {
            const localData = loadLocalData();
            const savedExams = localStorage.getItem('exams');
            // 打印数据，准备调试图表
            console.log(savedExams);
            if (localData) {
                processData(localData);
            } else {
                fetchExcelData().then(networkData => {
                    if (networkData) {
                        const processedData = processExcelData(networkData);
                        processData(processedData);
                    } else {
                        showInitialEmptyState('网络请求失败，请手动上传文件');
                    }
                });
            }
        });
    </script>
</body>

</html>